package com.duo.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.duo.dto.SetmealDTO;
import com.duo.dto.SetmealPageQueryDTO;
import com.duo.dto.SetmealUpdateDTO;
import com.duo.entity.Dish;
import com.duo.entity.Setmeal;
import com.duo.entity.SetmealDish;
import com.duo.exception.BaseException;
import com.duo.mapper.DishMapper;
import com.duo.mapper.SetmealDishMapper;
import com.duo.mapper.SetmealMapper;
import com.duo.service.SetmealService;
import com.duo.vo.DishItemVO;
import com.duo.vo.SetmealVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: Xrx
 * @Description:
 * @CreateTime: 2023/7/7 17:41
 */
@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal>
        implements SetmealService {

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;



    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        // 向套餐表插入数据
        this.save(setmeal);
        LambdaQueryWrapper<Setmeal> setmealWrapper = new LambdaQueryWrapper<>();
        setmealWrapper.eq(Setmeal::getSetmealName, setmeal.getSetmealName());
        setmeal = this.getOne(setmealWrapper);
        // 获取生成的套餐id
        Long setmealId = setmeal.getId();
        List<Long> dishIds = setmealDTO.getDishIds();
        dishIds.forEach(dishId -> {
            SetmealDish setmealDish = new SetmealDish();
            setmealDish.setSetmealId(setmealId);
            setmealDish.setDishId(dishId);
            setmealDishMapper.insert(setmealDish);
        });
        log.info("新增套餐成功");
    }

    /**
     * 删除套餐
     * @param setmealId
     */
    @Override
    public void delete(Long setmealId) {
        this.removeById(setmealId);
        LambdaQueryWrapper<Setmeal> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.eq(Setmeal::getId, setmealId);
        Setmeal setmeal = this.getOne(setmealDishWrapper);
        if (ObjectUtil.isNull(setmeal)) {
            log.info("套餐不存在");
            throw new BaseException("套餐不存在");
        }
        baseMapper.deleteById(setmealId);
        log.info("删除套餐成功");
    }


    /**
     * 删除套餐
     * @param setmealIds
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Long> setmealIds) {
        setmealIds.forEach(this::delete);
    }

    /**
     * 更新套餐
     * @param setmealDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SetmealUpdateDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        setmeal.setId(setmealDTO.getSetmealId());
        BeanUtils.copyProperties(setmealDTO, setmeal);
        this.updateById(setmeal);
        List<Long> dishIds = setmealDTO.getDishIds();
        if (CollUtil.isNotEmpty(dishIds)) {
            LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
            setmealDishWrapper.eq(SetmealDish::getSetmealId, setmeal.getId());
            setmealDishMapper.delete(setmealDishWrapper);
            dishIds.forEach(dishId -> {
                SetmealDish setmealDish = new SetmealDish();
                setmealDish.setSetmealId(setmeal.getId());
                setmealDish.setDishId(dishId);
                setmealDishMapper.insert(setmealDish);
            });
        }
        log.info("更新套餐成功");
    }

    /**
     * 根据id查询套餐和关联的菜品数据
     * @param id
     * @return
     */
    @Override
    public List<DishItemVO> getDishById(Long id) {
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(setmealDishWrapper);
        List<Long> dishIds = setmealDishes.stream().map(SetmealDish::getDishId).collect(Collectors.toList());
        LambdaQueryWrapper<Dish> dishWrapper = new LambdaQueryWrapper<>();
        dishWrapper.in(Dish::getId, dishIds);
        List<Dish> dishes = dishMapper.selectList(dishWrapper);
        List<DishItemVO> dishItemVOS = dishes.stream().map(dish -> {
            DishItemVO dishItemVO = new DishItemVO();
            BeanUtils.copyProperties(dish, dishItemVO);
            return dishItemVO;
        }).collect(Collectors.toList());
        return dishItemVOS;
    }

    /**
     * 分页查询套餐列表
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public List<SetmealVO> pageList(SetmealPageQueryDTO setmealPageQueryDTO) {
        Long categoryId = setmealPageQueryDTO.getCategoryId();
        String setmealName = setmealPageQueryDTO.getSetmealName();
        String description = setmealPageQueryDTO.getDescription();
        BigDecimal price = setmealPageQueryDTO.getPrice();
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealPageQueryDTO, setmeal);
        LambdaQueryWrapper<Setmeal> setmealWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(categoryId)) {
            setmealWrapper.eq(Setmeal::getCategoryId, categoryId);
        }
        if (ObjectUtil.isNotNull(setmealName)) {
            setmealWrapper.like(Setmeal::getSetmealName, setmealName);
        }
        if (ObjectUtil.isNotNull(description)) {
            setmealWrapper.like(Setmeal::getDescription, description);
        }
        if (ObjectUtil.isNotNull(price)) {
            setmealWrapper.eq(Setmeal::getPrice, price);
        }
        Page<Setmeal> page = new Page<>(setmealPageQueryDTO.getCurrent(), setmealPageQueryDTO.getSize());
        Page<Setmeal> setmealIPage = this.page(page, setmealWrapper);
        List<SetmealVO> setmealVOS = setmealIPage.getRecords().stream().map(item -> {
            SetmealVO setmealVO = new SetmealVO();
            setmealVO.setSetmealId(item.getId());
            BeanUtils.copyProperties(item, setmealVO);
            return setmealVO;
        }).collect(Collectors.toList());
        return setmealVOS;
    }



}
